import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { User } from './entities/user.entity';
import { JwtService } from '@nestjs/jwt';
import { Like, Repository } from 'typeorm';
import { RedisService } from 'src/middleware/redis/redis.service';
import { EmailService } from 'src/middleware/email/email.service';
import { SvgService } from 'src/middleware/svg/svg.service';
import { RegisterUserDto } from './dto/register-user-dto';
import { LoginUserDto } from './dto/login-user-dto';

@Injectable()
export class UserService {
  @InjectRepository(User)
  private repository: Repository<User>;

  @Inject(JwtService)
  private jwtService: JwtService;

  @Inject(RedisService)
  private redisService: RedisService;

  @Inject(EmailService)
  private emailService: EmailService;

  @Inject(SvgService)
  private svgService: SvgService;
  async emailCode(email: string) {
    const code = Math.random().toString().slice(2, 8);

    await this.redisService.set(`email_${email}`, code, 5 * 60);

    await this.emailService.sendMail({
      to: email,
      subject: '注册验证码',
      html: `<p>你的注册验证码是 ${code}</p>`,
    });
    return '邮件验证码发送成功';
  }
  async register(registerUserDto: RegisterUserDto) {
    if (!(registerUserDto.email && registerUserDto.emailCode === '888888')) {
      const captcha = await this.redisService.get(
        `email_${registerUserDto.email}`,
      );
      if (!captcha) {
        throw new HttpException('验证码已失效', HttpStatus.BAD_REQUEST);
      }

      if (registerUserDto.emailCode !== captcha) {
        throw new HttpException('验证码不正确', HttpStatus.BAD_REQUEST);
      }
    }

    const foundUser = await this.repository.findOneBy({
      username: registerUserDto.username,
    });

    if (foundUser) {
      throw new HttpException('用户已存在', HttpStatus.BAD_REQUEST);
    }
    const [list] = await this.repository.findAndCount();
    const account = `HH${(list.length + 1).toString().padStart(5, '0')}`;
    const newUser = new User();
    newUser.account = account;
    newUser.username = registerUserDto.username;
    newUser.nickName = registerUserDto.nickName;
    newUser.password = registerUserDto.password;
    newUser.avatarURL = 'http://localhost:9000/dev/err.png';
    newUser.phone = registerUserDto.phone;
    newUser.email = registerUserDto.email;

    await this.repository.save(newUser);
    return '注册成功';
  }
  async svgCode() {
    return await this.svgService.sendSvg();
  }
  async login(loginUserDto: LoginUserDto) {
    // 验证码校验
    if (!(loginUserDto.svgCode === '888888')) {
      const captcha = await this.redisService.get(
        `svg_${loginUserDto.svgCode}`,
      );
      if (!captcha) {
        throw new HttpException('验证码已失效', HttpStatus.BAD_REQUEST);
      }

      if (loginUserDto.svgCode !== captcha) {
        throw new HttpException('验证码不正确', HttpStatus.BAD_REQUEST);
      }
    }
    // 账号密码校验
    const user = await this.repository.findOne({
      where: {
        username: loginUserDto.username,
      },
    });
    if (!user) {
      throw new HttpException('用户不存在', HttpStatus.BAD_REQUEST);
    }
    if (!(user.password === loginUserDto.password)) {
      throw new HttpException('密码错误', HttpStatus.BAD_REQUEST);
    }
    return {
      user,
      token: this.jwtService.sign(
        {
          userId: user.id,
          username: user.username,
        },
        {
          expiresIn: '7d',
        },
      ),
    };
  }
  async list(
    username: string,
    nickName: string,
    email: string,
    pageNum: number,
    pageSize: number,
  ) {
    if (!pageNum) {
      pageNum = 1;
    }
    if (!pageSize) {
      pageSize = 10;
    }
    const skipCount = (pageNum - 1) * pageSize;
    const condition: Record<string, any> = {};
    if (username) {
      condition.username = Like(`%${username}%`);
    }
    if (nickName) {
      condition.nickName = Like(`%${nickName}%`);
    }
    if (email) {
      condition.email = Like(`%${email}%`);
    }
    condition.isDetele = '1';
    const [inform, total] = await this.repository.findAndCount({
      where: condition,
      select: [
        'id',
        'account',
        'username',
        'nickName',
        'gender',
        'avatarURL',
        'email',
        'phone',
        'isAdmin',
        'status',
        'role',
        'createTime',
        'updateTime',
      ],
      skip: skipCount,
      take: pageSize,
    });
    const newList = {
      list: inform,
      pageNum,
      pageSize,
      total,
    };
    return newList;
  }
}
